package org.tangjl.multidatasource.dynamic;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 动态数据源自动切换拦截
 *
 * @author tangjialin1@tcl.com on 2025-08-26.
 */
// @Order(Integer.MIN_VALUE) 设置这个顺序很重要，优先级需要高于 @Transactional 的优先级，否则拦截无效
@Order(Integer.MIN_VALUE)
@Aspect
@Component
public class DynamicDataSourceAspect {

    /**
     * 切换数据源
     *
     * @param point 连接点
     */
    @Around("@annotation(org.tangjl.multidatasource.dynamic.DataSource)")
    public Object switchDynamicDataSource(ProceedingJoinPoint point) throws Throwable {
        DataSource annotation = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(DataSource.class);
        if (Objects.isNull(annotation)) {
            annotation = point.getTarget().getClass().getAnnotation(DataSource.class);
        }
        if (Objects.nonNull(annotation)) {
            DynamicDataSourceContextHolder.set(annotation.value());
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clear();
        }
    }

}
